﻿using System;

namespace Eniux.SharpOpenGL
{
    /// <summary>
    /// 渲染上下文抽象类
    /// </summary>
    public abstract class RenderContext : IRenderContext
    {
        #region 变量

        /// <summary>
        /// 渲染上下文
        /// </summary>
        protected IntPtr renderContextHandle = IntPtr.Zero;

        /// <summary>
        /// 设备上下文
        /// </summary>
        protected IntPtr deviceContextHandle = IntPtr.Zero;

        /// <summary>
        /// 宽度
        /// </summary>
        protected int width = 0;

        /// <summary>
        ///高度
        /// </summary>
        protected int height = 0;

        /// <summary>
        ///位深
        /// </summary>
        protected int bitDepth = 0;

        /// <summary>
        /// GDI是否可用
        /// </summary>
        protected bool gdiDrawingEnabled = true;

        #endregion

        #region 属性

        /// <summary>
        /// 获取或设置上下文句柄
        /// </summary>
        public IntPtr RenderContextHandle
        {
            get { return renderContextHandle; }
            protected set { renderContextHandle = value; }
        }

        /// <summary>
        /// 获取或设置设备句柄
        /// </summary>
        public IntPtr DeviceContextHandle
        {
            get { return deviceContextHandle; }
            protected set { deviceContextHandle = value; }
        }

        /// <summary>
        /// 获取或设置宽度
        /// </summary>
        /// <value>宽度</value>
        public int Width
        {
            get { return width; }
            protected set { width = value; }
        }

        /// <summary>
        /// 获取或设置高度
        /// </summary>
        public int Height
        {
            get { return height; }
            protected set { height = value; }
        }

        /// <summary>
        /// 获取或设置位深
        /// </summary>
        public int BitDepth
        {
            get { return bitDepth; }
            protected set { bitDepth = value; }
        }

        /// <summary>
        /// 获取或设置GDI是否可用
        /// </summary>
        public bool GDIDrawingEnabled
        {
            get { return gdiDrawingEnabled; }
            protected set { gdiDrawingEnabled = value; }
        }

        #endregion

        #region 方法

        /// <summary>
        /// 创建渲染上下文
        /// </summary>
        /// <param name="gl">OpenGL上下文</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <param name="bitDepth">位深</param>
        /// <param name="parameter">参数</param>
        /// <returns>bool</returns>
        public virtual bool Create(OpenGL gl, int width, int height, int bitDepth, object parameter)
        {
            //  Set the width, height and bit depth.
            Width = width;
            Height = height;
            BitDepth = bitDepth;

            return true;
        }

        /// <summary>
        /// 销毁渲染上下文
        /// </summary>
        public virtual void Destroy()
        {
            if (renderContextHandle != IntPtr.Zero)
            {
                Win32.wglDeleteContext(renderContextHandle);
                renderContextHandle = IntPtr.Zero;
            }
        }

        /// <summary>
        /// 设置上下文尺寸.
        /// </summary>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        public virtual void SetDimensions(int width, int height)
        {
            Width = width;
            Height = height;
        }

        /// <summary>
        /// 确定渲染当前上下文
        /// </summary>
        public abstract void MakeCurrent();

        /// <summary>
        /// 将呈现位块的数据给上下文.
        /// </summary>
        /// <param name="hdc">The HDC.</param>
        public abstract void Blit(IntPtr hdc); 

        #endregion

        #region IDisposable接口

        /// <summary>
        /// 
        /// </summary>
        void IDisposable.Dispose()
        {
            //  Destroy the context provider.
            Destroy();
        }
        
        #endregion
    }
}
